package com.dailyblue.project.smbms.alibaba.provider.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dailyblue.project.smbms.alibaba.commons.bean.Provider;
import com.dailyblue.project.smbms.alibaba.commons.util.JsonResult;
import com.dailyblue.project.smbms.alibaba.commons.util.ResultTool;
import com.dailyblue.project.smbms.alibaba.provider.mapper.ProviderMapper;
import com.dailyblue.project.smbms.alibaba.provider.service.ProviderService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ProviderServiceImpl extends ServiceImpl<ProviderMapper, Provider> implements ProviderService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ProviderMapper mapper;
    // REDIS中对象的key前缀
    private final static String PROVIDER_KEY_SUFFIX = "PROVIDER::";
    // redis中集合的key
    private final static String PROVIDER_LIST = "PROVIDER_LIST";

    private final static String PAGE_INFO = "PAGE_INFO";

    @Override
    public JsonResult findProviderById(int id) {
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String str = valueOperations.get(PROVIDER_KEY_SUFFIX + id);
        log.info("redis:{}",str);
        if (str == null || "".equals(str)) {
            Provider prov = mapper.selectById(id);
            valueOperations.set(PROVIDER_KEY_SUFFIX + id, JSONArray.toJSONString(prov));
            log.info("从数据库中获取,{}",str);
            return ResultTool.success(prov);
        }
        Provider prov = JSONArray.parseObject(str, Provider.class);
        log.info("数据时：{}",prov);
        return ResultTool.success(prov);
    }

    @Override
    public JsonResult find(int page) {
        log.info("开始获取第{}页数据", page);
        // 首先在 redis 中查看是否存在数据
        ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        long size = listOperations.size(PROVIDER_LIST);
        if (size == 0) {
            log.info("第一次进入，填充数据，填充个数:{}", size);
            long len = mapper.selectCount(null);
            fullList(listOperations, len);
        }
        int start = (page - 1) * 5;
        int end = page * 5 - 1;
        List<String> keys = listOperations.range(PROVIDER_LIST, start, end);
        log.info("获取的起始:{},结束:{},内容:{}", start, end, keys);
        if (keys.get(0).equals("0")) {
            log.info("不存在第{}页数据，从数据库获取", page);
            // 如果redis不存在，则连接数据库返回并存放redis
            PageHelper.startPage(page, 5);
            List<Provider> list = list();
            fullList(listOperations, start, end, list);
            PageInfo<Provider> pageInfo = new PageInfo<>(list);
            valueOperations.set(PAGE_INFO, JSONArray.toJSONString(pageInfo));
            return ResultTool.success(pageInfo);
        }
        log.info("存在数据");
        // 如果redis中存在，则redis返回
        List<Provider> list = new ArrayList<>();
        for (int i = 0; i < keys.size(); i++) {
            String s = keys.get(i);
            String str = valueOperations.get(s);
            Provider provider = JSONArray.parseObject(str, Provider.class);
            list.add(provider);
        }
        String pi = valueOperations.get(PAGE_INFO);
        PageInfo<Provider> pageInfo = JSONArray.parseObject(pi, PageInfo.class);
        pageInfo.setList(list);
        return ResultTool.success(pageInfo);
    }

    @Override
    public JsonResult deleteProvider(int id, int page, int count) {
        // 删除数据库的内容
        int row = mapper.deleteById(id);
        if (row == 0) {
            return ResultTool.fail();
        }
        // 同步redis和数据库内容
        ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
        listOperations.remove(PROVIDER_LIST, 1, PROVIDER_KEY_SUFFIX + id);
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.getAndDelete(PROVIDER_KEY_SUFFIX + id);
        return find(count == 1 ? page - 1 : page);
    }

    private void fullList(ListOperations<String, String> listOperations, long size) {
        for (int i = 0; i < size; i++) {
            listOperations.rightPush(PROVIDER_LIST, "0");
        }
    }

    private void fullList(ListOperations<String, String> listOperations, int start, int end, List<Provider> list) {
        for (int i = start, j = 0; i <= end; i++, j++) {
            listOperations.set(PROVIDER_LIST, i, PROVIDER_KEY_SUFFIX + list.get(j).getId());
            findProviderById(list.get(j).getId());
        }
    }

    @Override
    public JsonResult saveProvider(Provider provider) {
        // 录入到数据库
        int row = mapper.insert(provider);
        if (row == 0) {
            return ResultTool.fail();
        }
        // 同步到redis
        provider = mapper.findLastProvider();
        ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        listOperations.rightPush(PROVIDER_LIST, PROVIDER_KEY_SUFFIX + provider.getId());
        valueOperations.set(PROVIDER_KEY_SUFFIX + provider.getId(), JSONArray.toJSONString(provider));
        return ResultTool.success();
    }

    @Override
    public JsonResult updateProvider(Provider provider, int page) {
        int row = mapper.updateById(provider);
        if (row == 0) {
            return ResultTool.fail();
        }
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String str = valueOperations.get(PROVIDER_KEY_SUFFIX + provider.getId());
        Provider beforeProvider = JSONArray.parseObject(str, Provider.class);
        // 更新信息
        beforeProvider.setProAddress(provider.getProAddress());
        beforeProvider.setProCode(provider.getProCode());
        beforeProvider.setProFax(provider.getProFax());
        beforeProvider.setProDesc(provider.getProDesc());
        beforeProvider.setProPhone(provider.getProPhone());
        beforeProvider.setProName(provider.getProName());
        beforeProvider.setProContact(provider.getProContact());
        valueOperations.set(PROVIDER_KEY_SUFFIX + provider.getId(), JSONArray.toJSONString(beforeProvider));
        return find(page);
    }
}
